<?php

namespace App\Kuafu\Shop\Service;

use App\Imports\Camera\CameraImport;
use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Shop\Enum\CodeEnum;
use App\Kuafu\Shop\Enum\ShopCodeEnum;
use App\Kuafu\Shop\Model\CameraModel;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Model\ShopAliyunEquipmentModel;
use App\Kuafu\User\Service\AuthService;
use Maatwebsite\Excel\Facades\Excel;


class ShopCameraService extends BaseService
{
    /**
     * 摄像头类型列表
     */
    public const SHOP_CAMERA_LIST_TEMP = [
        [
            'type'     => CodeEnum::SHOP_CAMERA_TYPE_1,
            'typeName' => CodeEnum::SHOP_CAMERA_TYPE_TEXT[CodeEnum::SHOP_CAMERA_TYPE_1],
            'name'     => '门口'
        ],
        [
            'type'     => CodeEnum::SHOP_CAMERA_TYPE_2,
            'typeName' => CodeEnum::SHOP_CAMERA_TYPE_TEXT[CodeEnum::SHOP_CAMERA_TYPE_2],
            'name'     => '收银机'
        ],
        [
            'type'     => CodeEnum::SHOP_CAMERA_TYPE_2,
            'typeName' => CodeEnum::SHOP_CAMERA_TYPE_TEXT[CodeEnum::SHOP_CAMERA_TYPE_2],
            'name'     => '后厨'
        ],
        [
            'type'     => CodeEnum::SHOP_CAMERA_TYPE_2,
            'typeName' => CodeEnum::SHOP_CAMERA_TYPE_TEXT[CodeEnum::SHOP_CAMERA_TYPE_2],
            'name'     => '仓库'
        ],
    ];

    public static function checkTempIsExist($temp, $list, $isReturn = false)
    {
        $is = false;
        foreach ($list as $value) {
            if ($temp['type'] == $value['type'] && $temp['name'] == $value['name']) {
                $is = true;
                if ($isReturn) {
                    return $value;
                }
            }
        }
        return $is;
    }

    /**
     * 获取门店摄像头列表
     *
     * @param int $shopId
     * @param int $supplier
     * @return array|string[]
     */
    public static function getShopCameraList(int $shopId, int $supplier = 0): array
    {
        $list = CameraModel::query()
                           ->select([
                               'tripleType',
                               'deviceSecret',
                               'id',
                               'name',
                               'type',
                               'serialNo',
                               'deviceName',
                               'productKey',
                               'mac'
                           ])
                           ->where('shopId', $shopId)
                            ->when($supplier > 0, function($query)use($supplier){
                                $query->where('supplier', $supplier);
                            })
                           ->where('deviceType', CameraModel::DEVICE_TYPE_CAMERA)
                           ->get()
                           ->toArray();

        $result = [];
        foreach ($list as $one) {
            $result[$one['mac']] = $one;
        }

        foreach ($list as $one) {
            $result[$one['mac']]['deviceName' . $one['tripleType']]   = $one['deviceName'];
            $result[$one['mac']]['productKey' . $one['tripleType']]   = $one['productKey'];
            $result[$one['mac']]['deviceSecret' . $one['tripleType']] = $one['deviceSecret'];
            $result[$one['mac']]['typeName']                          = CodeEnum::SHOP_CAMERA_TYPE_TEXT[$one['type']] ?? '';
        }


        return array_values($result);
    }

    /**
     * 保存摄像头列表
     */
    public static function saveCameraList(array $list)
    {
        // 删除原有的数据

        $formatList = [];
        foreach ($list as $item) {
            foreach (CodeEnum::SHOP_CAMERA_TYPE_TEXT as $k => $i) {
                $formatList[] = array_merge($item, [
                    'deviceName'   => $item['deviceName' . $k],
                    'productKey'   => $item['productKey' . $k],
                    'deviceSecret' => $item['deviceSecret' . $k],
                    'tripleType'   => $k
                ]);
            }
        }
        $list   = $formatList;
        $dnList = array_column($list, 'deviceName');


        CameraModel::query()->whereIn('deviceName', $dnList)->update(['isDeleted' => 1]);

        // 写入新数据
        collect($list)->chunk(300)->each(function ($item) {
            $insertData = [];
            foreach ($item as $one) {
                $one['type']  = self::getCameraType($one['typeName']);
                $insertData[] = [
                    'shopId'       => $one['shopId'],
                    'type'         => $one['type'],
                    'name'         => $one['name'],
                    'serialNo'     => $one['serialNo'],
                    'deviceName'   => $one['deviceName'],
                    'productKey'   => $one['productKey'],
                    'deviceSecret' => $one['deviceSecret'],
                    'tripleType'   => $one['tripleType'],
                    'mac'          => $one['mac'],
                    'createdAt'    => time(),
                    'updatedAt'    => time(),
                    'createdByUid' => AuthService::getUserId(),
                    'updatedByUid' => AuthService::getUserId(),
                ];
            }

            CameraModel::query()->insert($insertData);
        });

        return true;
    }

    /**
     * 获取对应的摄像头的类型
     *
     * @param string $typeName
     * @return int
     */
    public static function getCameraType(string $typeName): int
    {

        foreach (CodeEnum::SHOP_CAMERA_TYPE_TEXT as $key => $text) {
            if (strpos($typeName, $text) !== false) {
                return $key;
            }
        }

        return CodeEnum::SHOP_CAMERA_TYPE_2;
    }

    /**
     * 获取数据校验
     *
     * @param string $file
     * @return array
     */
    public static function checkExcelContent(string $file)
    {
        $dataArr = Excel::toArray(new CameraImport(), $file);
        $dataArr = $dataArr[0];

        // 校验通过的 数据
        $checkedArr = [];
        // 异常的 数据
        $checkErrArr = [];

        unset($dataArr[0]);
        unset($dataArr[1]);


        foreach ($dataArr as $dataOneKey => $dataOne) {

            if (empty($dataOne[3]) || empty($dataOne[4])) {
                continue;
            }

            $checkedArr[$dataOneKey] = [
                'rowId'         => $dataOneKey,
                'province'      => $dataOne[0],
                'city'          => $dataOne[1],
                'district'      => $dataOne[2],
                'shopCode'      => $dataOne[3],
                'typeName'      => CodeEnum::SHOP_CAMERA_TYPE_TEXT[self::getCameraType($dataOne[4])],
                'name'          => $dataOne[4],
                'mac'           => $dataOne[5],
                'serialNo'      => $dataOne[6],
                'deviceName1'   => $dataOne[7],
                'deviceSecret1' => $dataOne[8],
                'productKey1'   => $dataOne[9],
                'deviceName2'   => $dataOne[10],
                'deviceSecret2' => $dataOne[11],
                'productKey2'   => $dataOne[12]
            ];
        }

        $codeArr = array_column($checkedArr, 'shopCode');

        // 获取门店编号对应的门店数据
        $shopList = Shop::query()->whereIn('shopCode', $codeArr)->get()->toArray();
        // 判断 门店code 都在里面
        $checkCodeArr = self::excelCheckShopCode($checkedArr, $shopList);
        if (count($checkCodeArr) > 0) {
            foreach ($checkCodeArr as &$a) {
                unset($checkedArr[$a['rowId']]);
                $a['errMsg'] = 'shopCode 不存在';
            }
            $checkErrArr = array_merge($checkErrArr, $checkCodeArr);
            unset($a);
        }
        // 判断门店数据的省市区是否正常
        $checkCodeArr = self::excelCheckShopAddress($checkedArr, $shopList);
        if (count($checkCodeArr) > 0) {
            foreach ($checkCodeArr as &$a) {
                unset($checkedArr[$a['rowId']]);
                $a['errMsg'] = '省市区不匹配';
            }
            $checkErrArr = array_merge($checkErrArr, $checkCodeArr);
            unset($a);
        }

//        // 判断门店的设备编号是否存在
//        $checkCodeArr = self::excelCheckEquipment($checkedArr);
//        if (count($checkCodeArr) > 0) {
//            foreach ($checkCodeArr as &$a) {
//                unset($checkedArr[$a['rowId']]);
//                $a['errMsg'] = 'deviceName 不在我们的设备库';
//            }
//            $checkErrArr = array_merge($checkErrArr, $checkCodeArr);
//            unset($a);
//        }
//
//        // 判断门店序列号唯一
//        $checkCodeArr = self::excelCheckUniqueSerialNo($checkedArr);
//        if (count($checkCodeArr) > 0) {
//            foreach ($checkCodeArr as &$a) {
//                unset($checkedArr[$a['rowId']]);
//                $a['errMsg'] = '序列号重复';
//            }
//            $checkErrArr = array_merge($checkErrArr, $checkCodeArr);
//            unset($a);
//        }

        return [
            'successList' => array_values($checkedArr),
            'failureList' => array_values($checkErrArr),
            'shopList'    => $shopList,
        ];
    }

    /**
     * 校验 code 准确性
     *
     * @param array $codeList
     * @param array $shopList
     * @return array
     */
    public static function excelCheckShopCode(array &$codeList, array $shopList)
    {
        $shopList = array_column($shopList, null, 'shopCode');

        $diffCodeList = [];
        foreach ($codeList as &$list) {
            if (empty($shopList[$list['shopCode']])) {
                $diffCodeList[] = $list;
            }

            $list['shopId']   = $shopList[$list['shopCode']]['id'];
            $list['shopName'] = $shopList[$list['shopCode']]['name'];
        }

        unset($list);
        return $diffCodeList;
    }

    /**
     * excel 校验 城市 的 省市区
     *
     * @param array $fileList
     * @param array $shopList
     * @return array
     */
    public static function excelCheckShopAddress(array $fileList, array $shopList)
    {
        $shopList = array_column($shopList, null, 'shopCode');

        $diffCodeList = [];
        foreach ($fileList as $list) {

            if (empty($shopList[$list['shopCode']])) {
                $diffCodeList[] = $list;
            }

            $addressList = explode('-', $shopList[$list['shopCode']]['addressPrefix']);

            if (strpos($addressList[0], $list['province']) === false) {
                $diffCodeList[] = $list;
            }
            if (strpos($addressList[1], $list['city']) === false) {
                $diffCodeList[] = $list;
            }
//            if (strpos($addressList[2], $list['district']) === false) {
//                $diffCodeList[] = $list;
//            }
        }
        return $diffCodeList;
    }

    /**
     * excel 校验 城市 的 省市区
     *
     * @param array $fileList
     * @param array $shopList
     * @return array
     */
    public static function excelCheckEquipment(array &$fileList)
    {
        $dnList = array_column($fileList, 'deviceName');

        $equipmentList = ShopAliyunEquipmentModel::query()->whereIn('deviceName', $dnList)
                                                 ->get()
                                                 ->keyBy('deviceName');
        $diffCodeList  = [];
        foreach ($fileList as &$list) {
            if (empty($equipmentList[$list['deviceName']])) {
                $diffCodeList[] = $list;
            }
            $list['productKey'] = $equipmentList[$list['deviceName']]['productKey'] ?? '';
        }
        return $diffCodeList;
    }

    /**
     * excel 校验 序列号 唯一
     *
     * @param array $fileList
     * @param array $shopList
     * @return array
     */
    public static function excelCheckUniqueSerialNo(array &$fileList)
    {

        $list = array_column($fileList, null, 'serialNo');

        $rowList = array_column($list, null, 'rowId');

        $diffCodeList = [];
        foreach ($fileList as &$list) {
            if (empty($rowList[$list['rowId']])) {
                $diffCodeList[] = $list;
            }
        }
        $fileList = array_values($rowList);

        return $diffCodeList;
    }

    /**
     * 获取临时目录
     *
     * @return string
     */
    public static function getTempDir()
    {
        $dir = '/mnt/cdn/upload/tmp';
        if (!is_dir($dir)) {
            mkdir($dir, 0777, true);
        }

        $dir = rtrim($dir, "/");
        return $dir . "/";
    }
}
